package com.flyxiaozhu.erp.admin.controllers;

import com.flyxiaozhu.erp.admin.authorize.AdminUserDetails;
import com.flyxiaozhu.erp.admin.authorize.AuthorizeHelper;
import com.flyxiaozhu.erp.core.entities.AdminRole;
import com.flyxiaozhu.erp.core.entities.AdminUser;
import com.flyxiaozhu.erp.core.libs.ErrorCode;
import com.flyxiaozhu.erp.core.libs.JSONResult;
import com.flyxiaozhu.erp.core.libs.SearchSpecification;
import com.flyxiaozhu.erp.core.repositories.AdminRoleRepository;
import com.flyxiaozhu.erp.core.repositories.AdminUserRepository;
import com.flyxiaozhu.erp.core.utils.BeanUtils;
import com.flyxiaozhu.erp.core.utils.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
public class AdminUserController {

    @Autowired
    AdminUserRepository adminUserRepository;

    @Autowired
    AdminRoleRepository adminRoleRepository;

    @RequestMapping("/adminUser/getCurrentUser")
    public JSONResult getCurrentUser() {
        AdminUserDetails userDetails = AuthorizeHelper.getUserDetails();

        return new JSONResult()
                .put("user", userDetails.getAdminUser())
                .put("permission", AuthorizeHelper.getPermissions());
    }

    @Secured("ROLE_ADMIN_USER_SELECT")
    @RequestMapping("/adminUser/select")
    public JSONResult getUserList(HttpServletRequest request, @PageableDefault Pageable pageable) {

        Page<AdminUser> page = adminUserRepository.findAll(new SearchSpecification<>(request), pageable);

        List<Long> userIds = CollectionUtils.map(page.getContent(), AdminUser::getId);

        List<AdminRole> roles = adminRoleRepository.findByAdminUserIdIn(userIds);

        Map<Long, List<Long>> userIdGroup = CollectionUtils.group(roles, new CollectionUtils.GroupFilter<AdminRole, Long, Long>() {
            @Override
            public Long getKey(AdminRole source) {
                return source.getAdminUserId();
            }

            @Override
            public Long getValue(AdminRole source) {
                return source.getRoleId();
            }
        });
        for (AdminUser adminUser : page.getContent()) {
            adminUser.setRoleId(userIdGroup.get(adminUser.getId()));
        }

        return new JSONResult(page, pageable.getPageNumber());
    }

    @Secured("ROLE_ADMIN_USER_INSERT")
    @PostMapping("/adminUser/insert")
    public JSONResult addUser(AdminUser adminUser,
                              @RequestParam(value = "roleId", required = false) List<Long> roleId) {

        AdminUser adminUser1 = adminUserRepository.findAdminUserByUsername(StringUtils.trim(adminUser.getUsername()));

        if (adminUser1 != null) {
            return new JSONResult(ErrorCode.DUPLICATE_KEY, "该用户名已存在");
        }
        adminUser.setPassword(DigestUtils.md5Hex(adminUser.getTmpPwd()));
        adminUserRepository.save(adminUser);

        if (roleId != null) {
            assigningRoles(adminUser.getId(), roleId);
        }
        adminUser.setTmpPwd("******");

        return new JSONResult().put("model", adminUser);
    }

    @Transactional
    @Secured("ROLE_ADMIN_USER_UPDATE")
    @PostMapping("/adminUser/update")
    public JSONResult updateUser(AdminUser adminUser,
                                 @RequestParam(value = "roleId", required = false) List<Long> roleId) {

        AdminUser user = adminUserRepository.findById(adminUser.getId()).orElse(null);

        if (user == null) {
            return new JSONResult(ErrorCode.NO_DATA, "该用户不存在");
        }

        AdminUser user1 = adminUserRepository.findAdminUserByUsername(StringUtils.trim(adminUser.getUsername()));
        if (user1 != null && user1.getId() != adminUser.getId()) {
            return new JSONResult(ErrorCode.DUPLICATE_KEY, "该用户名已存在");
        }

        BeanUtils.copyProperties(adminUser, user);

        if (!adminUser.getTmpPwd().equals("******")) {
            user.setPassword(DigestUtils.md5Hex(adminUser.getTmpPwd()));
        }

        adminUserRepository.save(user);

        adminRoleRepository.deleteByAdminUserId(adminUser.getId());

        if (roleId != null) {
            assigningRoles(adminUser.getId(), roleId);
        }

        user.setTmpPwd("******");

        return new JSONResult().put("count", 1).put("model", user);
    }

    private void assigningRoles(Long userId, Collection<Long> roleIds) {

        for (Long roleId : roleIds) {
            AdminRole ar = new AdminRole();
            ar.setAdminUserId(userId);
            ar.setRoleId(roleId);
            adminRoleRepository.save(ar);
        }
    }

}
